package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.StatusConstant;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.entity.DishFlavor;
import com.sky.mapper.CategoryMapper;
import com.sky.mapper.DishFlavorMapper;
import com.sky.mapper.DishMapper;
import com.sky.result.PageResult;
import com.sky.service.DishService;
import com.sky.vo.DishVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.Array;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

@Service
@Slf4j
public class DishServiceImpl implements DishService {

    @Resource
    private DishMapper dishMapper;

    @Resource
    private DishFlavorMapper dishFlavorMapper;


    @Transactional(rollbackFor = SQLException.class)
    @Override
    public Integer addDish(DishDTO dishDTO) {

        // 写入菜品
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);

        log.info("【新增菜品前】dish：{}",dish);
        Integer tag = dishMapper.insertDish(dish);
        log.info("【新增菜品后】dish：{}",dish);


        // 插入口味
        Long dishId = dish.getId();
        List<DishFlavor> flavors = dishDTO.getFlavors();
        if ( flavors != null && flavors.size() > 0) {
            flavors.stream().forEach(dishFlavor -> {
                dishFlavor.setDishId(dishId);
                dishFlavorMapper.insertFlavor(dishFlavor);
            });
        }
        return tag;
    }




    @Override
    public PageResult findByPage(DishPageQueryDTO dishPageQueryDTO) {
        // 分页插件配置
        PageHelper.startPage(dishPageQueryDTO.getPage(),dishPageQueryDTO.getPageSize());

        // 开始分页查询
        List<DishVO> dishVOS = dishMapper.selectByPage(dishPageQueryDTO);

        // 强转成page类型
        Page<DishVO> page = (Page<DishVO>) dishVOS;

        return new PageResult(page.getTotal(),page.getResult());
    }

    @Transactional(rollbackFor = SQLException.class)
    @Override
    public Integer batchRemove(List<Long> ids) {

        // 先删除菜品
        Integer tag = dishMapper.deleteByIds(ids);
        // 批量删除口味
        dishFlavorMapper.deleteByIds(ids);
        return tag;
    }



    @Override
    public DishVO findById(Long id) {

        // 将 dish 转换成 dishvo
        DishVO dishVO = new DishVO();
        Dish dish = dishMapper.selectById(id);
        BeanUtils.copyProperties(dish, dishVO);

        // 查询口味表
        List<DishFlavor> dishFlavors = dishFlavorMapper.selectByDishId(dish.getId());
        dishVO.setFlavors(dishFlavors);
        return dishVO;
    }

    @Transactional(rollbackFor = SQLException.class)
    @Override
    public Integer udpateById(DishDTO dishDTO) {
        // 将dto 转换成 实体类
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);

        List<DishFlavor> flavors = dishDTO.getFlavors();

        // 更具id更新
        Integer tag = dishMapper.updateById(dish);

        // 将原有菜品的口味删除
        dishFlavorMapper.deleteByDishId(dish.getId());

        if (flavors.size() >0 && flavors != null) {
            flavors.stream().forEach(dishFlavor -> {
                dishFlavor.setDishId(dish.getId());
                dishFlavorMapper.insertFlavor(dishFlavor);
            });
        }
        return tag;
    }

    @Override
    public List<DishVO> findByCategoryId(Long categoryId) {

        Dish dish = Dish.builder().categoryId(categoryId)
                .status(StatusConstant.ENABLE)
                .build();

        return dishMapper.selectByCategoryId(dish);
    }



    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    /**
     * 条件查询菜品和口味
     * @param dish
     * @return
     */
    public List<DishVO> listWithFlavor(Dish dish) {

        // 先查询缓存，缓存有，直接返回，缓存没有，读取数据库，并将数据缓存再redis中
        // 先查询缓存
        String key = "dish_"+dish.getCategoryId();
        Object objcList = redisTemplate.opsForValue().get(key);
        if (objcList != null) {
            log.info("【从Redis缓存中读取菜品信息】");
            List<DishVO> dishVOS = (List<DishVO>) objcList;
            return dishVOS;
        }

        // 缓存中没有，查询数据库

        List<Dish> dishList = dishMapper.list(dish);
        List<DishVO> dishVOList = new ArrayList<>();
        for (Dish d : dishList) {
            DishVO dishVO = new DishVO();
            BeanUtils.copyProperties(d,dishVO);

            //根据菜品id查询对应的口味
            List<DishFlavor> flavors = dishFlavorMapper.selectByDishId(d.getId());

            dishVO.setFlavors(flavors);
            dishVOList.add(dishVO);
        }

        log.info("【从数据库中读取数据，并写入redis。。。。】");
        // 将数据写入redis
        redisTemplate.opsForValue().set(key,dishVOList);

        return dishVOList;
    }

}
